package com.dark.front.web.controller;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.ExcessiveAttemptsException;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

import com.dark.common.Constants;
import com.dark.common.utils.IpUtils;
import com.dark.common.web.controller.BaseController;
import com.dark.common.web.model.LoginUser;
import com.dark.common.web.validate.AjaxResponse;
import com.dark.sys.service.UserService;
import com.dark.sys.util.UserLogUtils;
import com.dark.sys.web.dto.UserDto;

@Controller
@RequestMapping("/front")
public class LoginController extends BaseController {

	@Autowired
	private UserService userService ;
	
	/**
	 * 后台登录页面
	 * @return
	 */
	@RequestMapping(value={"", "/{login:login;?.*}"}, method=RequestMethod.GET)
	public String loginForm() {
		return viewName("login") ;
	}
	
	/**
	 * 登录
	 * @param dto
	 * @param request
	 * @return
	 */
	@ResponseBody
	@RequestMapping(value="/login", method=RequestMethod.POST)
	public AjaxResponse login(UserDto dto, HttpSession session, HttpServletRequest request) {
		if(StringUtils.isEmpty(dto.getUsername()) || StringUtils.isEmpty(dto.getPassword())) {
			return new AjaxResponse(false, "用户名和账号不能为空") ;
		}
		
		AjaxResponse ajaxResp = new AjaxResponse() ;
		
		Subject subject = SecurityUtils.getSubject() ;
		if (subject != null && subject.isAuthenticated()) {
            subject.logout();
        }
		UsernamePasswordToken token = new UsernamePasswordToken(dto.getUsername(), dto.getPassword()) ;
		
		try {
			
			subject.login(token);
			
		} catch(UnknownAccountException uae){  
			UserLogUtils.log(dto.getUsername(), "Username does not exist", "用户名不存在");
            ajaxResp.setStatus(false);ajaxResp.setMessage("用户名不存在");
        } catch(IncorrectCredentialsException ice){
        	UserLogUtils.log(dto.getUsername(), "Incorrect password", "密码不正确");
            ajaxResp.setStatus(false);ajaxResp.setMessage("密码不正确");
        } catch(LockedAccountException lae){  
        	UserLogUtils.log(dto.getUsername(), "Locked account", "账户已被锁定");
            ajaxResp.setStatus(false);ajaxResp.setMessage("账户已锁定");
        } catch(ExcessiveAttemptsException eae){  
        	UserLogUtils.log(dto.getUsername(), "Username or password error too much", "用户名或密码错误次数过多");
            ajaxResp.setStatus(false);ajaxResp.setMessage("用户名或密码错误次数过多");
        } catch(AuthenticationException ae){  
        	//通过处理Shiro的运行时AuthenticationException就可以控制用户登录失败或密码错误时的情景  
        	UserLogUtils.log(dto.getUsername(), "Incorrect user name or password", "用户名或密码不正确");
            ajaxResp.setStatus(false);ajaxResp.setMessage("用户名或密码不正确");
        }
		
		
		//验证是否登录成功
		if(subject.isAuthenticated()) {
			
			UserDto user = this.userService.getByUsername(dto.getUsername()) ;

			LoginUser cu = new LoginUser() ;
			cu.setUser(user);
			cu.setIp(IpUtils.getIpAddr(request));
			
			session.setAttribute(Constants.CURRENT_USER, cu);

			
			UserLogUtils.log(dto.getUsername(), "Login Success", "登录验证成功");
			ajaxResp.setStatus(true);ajaxResp.setMessage("登录验证成功");
			return ajaxResp ;
		} else {
			token.clear() ;
			return ajaxResp ;
		}
	}
	
	/** 
     * 用户登出 
     */  
    @RequestMapping("/logout")  
    public String logout(HttpServletRequest request){  
         SecurityUtils.getSubject().logout();  
         return InternalResourceViewResolver.REDIRECT_URL_PREFIX + "/";  
    }  
    
    /**
	 * 403 没有权限
	 * @return
	 */
	@RequestMapping(value={"/unauthor", "/403"}, method=RequestMethod.GET)
	public String unauthor() {
		return "error/403" ;
	}
	
}
